/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Model;

import Controller.CustomerManager;
import Controller.LogManager;
import Controller.UserManager;
import java.io.IOException;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 *
 * @author pauld
 */
@WebServlet(name="register", urlPatterns={"/register"})
public class register extends HttpServlet{
    HttpSession regSession= null;
    private static String username = null,
            password1 = null,
            password2 = null,
            email = null,
            lname = null,
            fname = null,
            mname = null,
            address = null,
            country = null,
            zip = null;
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
            
        int result = CustomerManager.addUser(username, password1, email, lname, fname, mname, address, country, zip);
        
        switch(result){
            case 1:
                //if the user has successfull registered
                LogManager.logEvent("Register." + Thread.currentThread().getStackTrace()[1].getMethodName(), Level.INFO, "Register Successful: " + username, request.getRemoteAddr(), "Not Logged In");
                response.sendRedirect("login.jsp");
                break;
            case -1:
                //if there is an error in the database
                LogManager.logEvent("Register." + Thread.currentThread().getStackTrace()[1].getMethodName(), Level.SEVERE, "Register Unsuccessful", request.getRemoteAddr(), "Not Logged In");
                response.sendRedirect("register.jsp?status=-1");
                break;
            case 2:
                //if the desired username is already taken
                LogManager.logEvent("Register." + Thread.currentThread().getStackTrace()[1].getMethodName(), Level.WARNING, "Register Unsuccessful", request.getRemoteAddr(), "Not Logged In");
                response.sendRedirect("register.jsp?status=2");
                break;
        }
        
    }
    
    //method for checking the user inputs
    //returns boolean 
    //true if user inputs are valid and fals otherwise
    private static boolean checkInput(HttpServletRequest request){
        //get the form values and store them on the variables
        username = request.getParameter("register-uname");
        password1 = request.getParameter("register-pw1");
        password2 = request.getParameter("register-pw2");
        email = request.getParameter("register-email");
        lname = request.getParameter("register-last_name");
        fname = request.getParameter("register-first_name");
        mname = request.getParameter("register-middle_initial");
        address = request.getParameter("register-add");
        country = request.getParameter("register-country");
        zip = request.getParameter("register-zip");
        
        //regex statements for validating form inputs
        String regexEmail = "^[A-Za-z0-9._%'-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$", //whitelist
                regexNum = "^[0-9]+$", //whitelist
                regexAlpha = "^[A-Za-z ]+$", //whitelist
                regexAlphaNum = "^[A-Za-z0-9]+$", //whitelist
                regexXSS = "[<(.*?)>]"; //blacklist
        
        Pattern pEmail = Pattern.compile(regexEmail, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE),
                pNum = Pattern.compile(regexNum, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE),
                pAlpha = Pattern.compile(regexAlpha, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE),
                pAlphaNum = Pattern.compile(regexAlphaNum, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE),
                pXSS = Pattern.compile(regexXSS, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
        
        Matcher mEmail = pEmail.matcher(email),
                mZip = pNum.matcher(zip),
                mUsername = pAlphaNum.matcher(username),
                mPW1 = pAlphaNum.matcher(password1),
                mPW2 = pAlphaNum.matcher(password2),
                mLname = pAlpha.matcher(lname),
                mFname = pAlpha.matcher(fname),
                mMname = pAlpha.matcher(mname),
                mAdd = pXSS.matcher(address),
                mCountry = pAlpha.matcher(country);
        
        boolean resultEmail = mEmail.find(),
                resultZip = mZip.find(),
                resultUsername = mUsername.find(),
                resultPW1 = mPW1.find(),
                resultPW2 = mPW2.find(),
                resultLname = mLname.find(),
                resultFname = mFname.find(),
                resultMname = mMname.find(),
                resultAdd = mAdd.find(),
                resultCountry = mCountry.find();
        
        //check the length and validity of the user inputs
        if( (username.length() >= 4 && username.length() <= 25) &&              //check length username
            (password1.length() >= 8 && password1.length() <= 25) &&            //check length of the password
            (password2.length() >= 8 && password2.length() <= 25) &&
            (password1.equals(password2)) &&
            (email.length() > 0 && email.length() <= 25) &&
            (lname.length() > 0 && lname.length() <= 25) &&
            (fname.length() > 0 && fname.length() <= 25) &&
            mname.length() == 1 && 
            (address.length() > 0 && address.length() <= 45) &&
            (country.length() != 0) && 
            (zip.length() == 4) && 
                resultEmail && 
                resultZip &&
                resultUsername &&
                resultPW1 &&
                resultPW2 &&
                resultLname &&
                resultFname &&
                resultMname &&
                !resultAdd &&
                resultCountry )
            return true;
        else
        {
            LogManager.logEvent("Register." + Thread.currentThread().getStackTrace()[1].getMethodName(), Level.WARNING, "Register Unsuccessful - Invalid Input", request.getRemoteAddr(), "Not Logged In");
            return false;
        }
    }
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        regSession = request.getSession();
        
        if( checkInput(request) ){
            regSession.setAttribute("reg-uname", "");
            regSession.setAttribute("reg-email", "");
            regSession.setAttribute("reg-lname", "");
            regSession.setAttribute("reg-fname", "");
            regSession.setAttribute("reg-mname", "");
            regSession.setAttribute("reg-add", "");
            regSession.setAttribute("reg-country", "");
            regSession.setAttribute("reg-zip", "");
            
            processRequest(request, response);
        }
        else{
            //if the registration is unsuccessufll then set the 
            //session values for user convinience
            
            regSession.setAttribute("reg-uname", username);
            regSession.setAttribute("reg-email", email);
            regSession.setAttribute("reg-lname", lname);
            regSession.setAttribute("reg-fname", fname);
            regSession.setAttribute("reg-mname", mname);
            regSession.setAttribute("reg-add", address);
            regSession.setAttribute("reg-country", country);
            regSession.setAttribute("reg-zip", zip);
            
            response.sendRedirect("register.jsp?status=0");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        regSession = request.getSession();
        
        if( checkInput(request) ){
            //if the registration is successfull then invalidate the session
            
            regSession.setAttribute("reg-uname", "");
            regSession.setAttribute("reg-email", "");
            regSession.setAttribute("reg-lname", "");
            regSession.setAttribute("reg-fname", "");
            regSession.setAttribute("reg-mname", "");
            regSession.setAttribute("reg-add", "");
            regSession.setAttribute("reg-country", "");
            regSession.setAttribute("reg-zip", "");
            
            processRequest(request, response);
        }
        else{
            //if the registration is unsuccessufll then set the 
            //session values for user convinience
            regSession.setAttribute("reg-uname", username);
            regSession.setAttribute("reg-email", email);
            regSession.setAttribute("reg-lname", lname);
            regSession.setAttribute("reg-fname", fname);
            regSession.setAttribute("reg-mname", mname);
            regSession.setAttribute("reg-add", address);
            regSession.setAttribute("reg-country", country);
            regSession.setAttribute("reg-zip", zip);
            
            response.sendRedirect("register.jsp?status=0");
        }
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }
    
}
